<template>
  <div class="login-page">
    <div class="bg">
      <img src="@/assets/bg.jpg" alt="" v-if="isDark === 'dark'">
      <!-- <video src="http://chst.vip:8081/crm-备分/media/bg-video.d2d602a9.mp4" loop muted>
      </video> -->
      <img v-else src="@/assets/bg3.jpg" alt="">
    </div>
    <div class="login-container">
      <div class="login-inner">
        <h1 class="title">crm系统</h1>
        <div class="common-login">
          <el-form ref="loginFormRef" :model="loginForm" status-icon :rules="rules" label-width="120px"
                   class="demo-loginForm">
            <!-- 用户名 -->
            <el-form-item label="用户名" prop="username" class="username-form-item">
              <el-input type="input" v-model="loginForm.username" autocomplete="off" />
            </el-form-item>
            <!-- 密码 -->
            <el-form-item label="密码" prop="password">
              <el-input @keydown.enter="submitForm(loginFormRef)" type="password" show-password
                        v-model="loginForm.password" autocomplete="off" />
            </el-form-item>

            <!-- 验证码 -->
            <!-- <el-form-item label="验证码" prop="captcha" class="captcha">
              <el-input v-model="loginForm.captcha" maxlength="5" @keydown.enter="submitForm(loginFormRef)"/>
              <span v-html="captchaEl" @click="getCaptcha" v-loading="captchaLoading"></span>
            </el-form-item> -->
            <!-- 登入按钮 -->
            <el-form-item>
              <el-button type="primary" @click="submitForm(loginFormRef)">登入</el-button>
            </el-form-item>
          </el-form>
          <el-form-item>
            <!-- 滑块验证码模块 -->
            <div class="slidercaptcha card" v-if="showSlider">
              <div class="card-header">
                <span>请完成安全验证!</span>
              </div>
              <div class="card-body">
                <div id="captcha" ref="sliderEl"></div>
              </div>
            </div>
          </el-form-item>
        </div>
      </div>
    </div>

  </div>
</template>
<script setup>
//引入store
import useUser from "../../store/users"
//引入ElLoading
import { ElLoading, ElMessage } from "element-plus"
//引入路由的钩子
import { useRouter } from "vue-router"
import { ref, reactive, onMounted } from "vue"
// 引入发送请求的方式
import * as api from "@/api/users"

//引入滑块验证码
import slider from "myx-slider-captcha"
import "myx-slider-captcha/slider-captcha.min.css"
import usePermission from "@/store/permission"

//判断是否是暗黑模式

import { useStorage } from "@vueuse/core"

let isDark = useStorage('vueuse-color-scheme');
//创建ref引用滑块验证码容器

let sliderEl = ref(null)
let showSlider = ref(false)

let sliderSrcs = [
  "https://www.heishenhua.com/img/screenshot/blackmyth_wukong_screenshot_019.jpg",
  "https://www.heishenhua.com/img/screenshot/blackmyth_wukong_screenshot_014.jpg",
  "https://www.heishenhua.com/img/screenshot/blackmyth_wukong_screenshot_015.jpg",
  "https://www.heishenhua.com/img/screenshot/blackmyth_wukong_screenshot_031.jpg"
]

//滑动验证的方法
let startSlider = () => {

  //声明一个promise
  //声明变量引用promise的resolve和reject

  let _resolve = null;
  let _reject = null;
  let sliderPromise = new Promise((resolve, reject) => {
    _resolve = resolve;
    _reject = reject;
  })
  //显示容器
  showSlider.value = true;
  nextTick(() => {
    slider({
      id: 'captcha',
      width: 300,
      height: 150,
      sliderL: 50,
      sliderR: 9,
      offset: 10,
      loadingText: '正在加载中...',
      failedText: '再试一次',
      barText: '向右滑动填充拼图',
      repeatIcon: 'fa fa-redo',
      setSrc(){
        return "https://chst.vip/images/img-1694662513953.webp"
      },
      onSuccess() {
        //验证通过
        //关闭滑动验证框
        showSlider.value = false;
        // console.log('验证通过')
        _resolve(true)
      },
      onFail() {
        //验证失败
        // console.log('验证失败')
        ElMessage.error('滑动验证失败')
      }
    })
  })

  return sliderPromise
}


//路由api对象

let router = useRouter();

//创建一个引用引用form组件
const loginFormRef = ref()

// 用户名校验规则
const validateUsername = (rule, value, callback) => {
  // 3到16位（字母，数字，下划线，减号）
  let pattern = /^[a-zA-Z0-9_-]{3,16}$/;

  if (pattern.test(value)) {
    callback()
  } else {
    callback('3到16位(字母,数字,下划线,减号)')
  }

}
// 密码校验规则
const validatePassword = (rule, value, callback) => {
  //从环境文件获取密码正则
  let pwdPattern = new RegExp(import.meta.env.VITE_APP_PWDPATTERN)
  //获取开发环境
  let env = import.meta.env.MODE;
  // console.log(import.meta.env)
  if (pwdPattern.test(value)) {
    callback()
  } else {
    let errorMsg = env === 'production' ? '密码必须包含大小写和一个字符' : "密码输入不能为空"
    callback(errorMsg)
  }
}
//验证码校验规则
const validatecaptcha = (rule, value, callback) => {
  // console.log(value)
  if (value.length) {
    callback()
  } else {
    callback('请输入验证码')
  }
}

// 表单Form数据源
const loginForm = reactive({
  username: "",
  password: "",
  captcha: ""
})

//表单验证规则
const rules = reactive({
  username: [{ validator: validateUsername, trigger: 'blur' }],
  password: [{ validator: validatePassword, trigger: 'blur' }],
  captcha: [{ validator: validatecaptcha, trigger: 'blur' }],
})

//校验整个表单的方法 
const submitForm = (formEl) => {
  if (!formEl) return
  formEl.validate(async (valid) => {
    //表单验证通过 打开loading动画
    if (valid) {
      //本地表单校验通过
      let loading = null;
      try {
        //等待先校验验证码
        // await verifyCaptcha()
        let verify = await startSlider();
        // console.log(verify)
        if (!verify) {
          //如果滑块验证不通过
          return
        }
        //验证通过之后 打开加载动画
        loading = ElLoading.service({
          lock: true,
          text: '正在登入...',
          background: 'rgba(0, 0, 0, 0.7)',
        })
        //发起登入请求
        let res = await api.loginApi(loginForm.username, loginForm.password);
        // console.log(res)
        //登入成功之后将数据存储到store
        let userStore = useUser();

        let permissionStore = usePermission();
        // console.log(permissionStore)
        //给userStore设置数据
        userStore.$patch({
          userInfo: res.userInfo,
          token: res.token,
          permissButtons: res.permission.buttons
        })
        //使用permissStore用于设置当前登入用户的角色权限
        await permissionStore.setCurrentRole({ roleid: res.userInfo.roleid, type: 1 })
        //关闭加载动画
        loading.close()
        //跳转到主页
        router.push("/")
      } catch (e) {
        console.log(e)
        loading.close()
      }

      //验证码校验通过才发起登入请求

    } else {
      //本地表单校验不通过
      console.log('error submit!')
      return false
    }
  })
}


//验证码逻辑
//captcha解构
let captchaEl = ref();
//captcha加载动画
let captchaLoading = ref(false)
//获取验证码
let getCaptcha = async () => {
  captchaLoading.value = true;
  try {
    //获取验证码
    let res = await api.getCaptchaApi();
    // console.log(res)
    captchaEl.value = res.img
    //关闭加载动画
    captchaLoading.value = false
  } catch (e) {
    console.log(e.toString())
    captchaLoading.value = false
  }
}
//校验验证码
let verifyCaptcha = async () => {
  //发起请求
  try {
    let res = await api.verifyCaptchaApi(loginForm.captcha.toLowerCase());
    // console.log(res)
    return Promise.resolve(true)
  } catch (e) {
    console.log(e)
    return Promise.reject(false)
  }
}




onMounted(() => {
  getCaptcha()
})

</script>

<style scoped lang="scss">
/* 修改element-plus样式的思路 */
/* 核心思路:重新编写样式,覆盖默认的element-plus的样式 */
/* 三种方式 */
/* 1. 直接找到当前组件的dom结构中的类名或者id等等,直接编写样式进行覆盖 */
/* 2. 在模块化样式的时候,可以通过深度选择器来完成样式的编写 :deep() */
/* 3. 全局样式,一般会定义一个全局的专门用于覆盖el-plus样式的文件,将样式编写在全局文件中 */

/* 遇到问题: */
/* 
1.检查类名是否正确

2.检查权重

3.是否需要使用深度选择器 */

.login-page {
  .bg {

    video,
    img {
      position: fixed;
      left: 0;
      right: 0;
      bottom: 0;
      top: 0;
    }
  }

  .login-container {
    position: fixed;
    z-index: 99;
    // background:#fff;
    min-width: 400px;
    min-height: 400px;
    right: 10%;
    bottom: 15%;
    background-color: rgba(0, 0, 0, .3);
    color: #fff;
    border-radius: 20px;

    .login-inner {
      margin-top: 55px;
      width: 100%;

      .toggle {
        text-align: center;
        // text-decoration: underline;
        margin: 30px 0;

        b {
          cursor: pointer;
        }
      }

      .title {
        text-align: center;
        color: #fff;
        margin-bottom: 30px;
      }

      :deep(.icon) {
        width: 2em;
        height: 2em;
        margin-right: 5px;
        vertical-align: middle;
      }
    }

  }
}

.captcha {
  display: flex;

  :deep(.el-input) {
    width: 100px;
    border-right: none;

    .el-input__wrapper {
      border-radius: 5px 0 0 5px;
      box-shadow: none;
    }
  }

  span {
    height: 42px;
    background-color: #fff;
    display: inline-block;
    border-left: none;
    border-radius: 0 5px 5px 0;
    width: 60%;
    cursor: pointer;
  }
}

//滑动验证码样式
.slidercaptcha {
  margin: 0 auto;
  width: 335px;
  height: 286px;
  border-radius: 4px;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.125);
  margin-top: 40px;
  position: fixed;
  z-index: 99999;
  background: var(--theme-bg);
  bottom: 22%;
  right: 12.5%;
  border-radius: 10px;
  font-size: 16px;
  font-weight: bolder;
}

.slidercaptcha .card-body {
  padding: 1rem;
}

.slidercaptcha canvas:first-child {
  border-radius: 4px;
  border: 1px solid #e6e8eb;
}

.slidercaptcha.card .card-header {
  background-image: none;
  // color: #000;
  color: #fff;
}

.refreshIcon {
  top: -54px;
}

.el-form {
  padding-right: 50px;
  margin-left: -20px;

  :deep(.el-button--primary) {
    height: 40px;
    width: 250px;
    background: var(--theme-bg)
  }
}

:deep(.el-form-item__label) {
  color: #fff;
  line-height: 40px;
}

:deep(.el-input__inner) {
  height: 40px;
}
</style>


